<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        
        let obj={
            age:30
        }

        function getPage(a,b,c){
            console.log(this.age,a,b,c)
        }

        // 封装call
        function myCall(context){
            if(typeof this!=="function"){
                return new Error('调用者不是一个函数')
            }
            // 判断this
            context=context||window
            // 在原型上添加一个方法
            context.fun=this
            // 获取参数
            let args=[...arguments].slice(1)
            let res=context.fun(...args)
            delete res
            return res
        }
        // 添加到函数原型上
        Function.prototype.myCall=myCall
        getPage.myCall(obj,1,2,3)


        // 封装apply
         function myApply(context){
            
            if(typeof this !== 'function'){
                return new Error("调用者不是一个函数")
            }
            // 判断是否存在
            context=context||window
            // 改变this指向
            context.fun=this
            // 获取参数
            let argus=[...arguments][1]
            // 调用该函数
            let res=context.fun(...argus)
            return res
         }
         Function.prototype.myApply=myApply
         getPage.myApply(obj,[1,2])

        // bind封装
        function myBind(context){

            // 判断调用者是否是函数
            if(typeof this!=='function'){
                return new Error("调用者不是一个函数")
            }
            // 判断需要指向的this是否存在
            context=context||window
            // 保存下this
            let _this=this
            // 获取参数
            let args=[...arguments][1]
            // 返回一个函数  bind的特色
            return function Fun(){
                if(this instanceof Fun){
                    // new容错   拼接新的参数
                    return new _this.apply(context,args.concat(...arguments))
                }else{
                    // 返回   拼接新的参数
                    return _this.apply(context,args.concat(...arguments))
                }
            }
        }
        Function.prototype.myBind=myBind
        let ss=getPage.myBind(obj,[12,3])(4)
    </script>
</body>
</html>